home *** CD-ROM | disk | FTP | other *** search
- /*
- * ham8.c Michael Saunby M.Saunby@reading.ac.uk
- *
- * Release 1.1 December 1992 A public screen plus utilities to give a pseudo
- * 24 bit display on Amigas with AGA graphics (A1200 and A4000).
- *
- * The AGA HAM-8 mode allows 64 colours to be defined - 48 of these will be
- * defined by this program (see display24.c) leaving 8 for intuition and
- * client programs.
- */
- #include <intuition/intuition.h>
- #include <graphics/gfxbase.h>
- #include <graphics/displayinfo.h>
- #include <intuition/screens.h>
- #include <dos/dosextens.h>
- #include <dos/rdargs.h>
- #include <exec/memory.h>
- #include <exec/types.h>
- #include <libraries/dos.h>
- #include <libraries/dosextens.h>
- #include <libraries/gadtools.h>
-
- #include <clib/exec_protos.h>
- #include <clib/intuition_protos.h>
- #include <clib/graphics_protos.h>
- #include <clib/gadtools_protos.h>
- #include <clib/dos_protos.h>
- #include <clib/alib_protos.h>
-
- #include <stdio.h>
- #include <stdlib.h>
-
- #include "display24.h"
-
- /*
- * If you turn this into something different feel free to change this, but if
- * you don't leave it alone!!
- */
- #define COPYRIGHT_MESSAGE "Version 1.1\nDecember 1992\n\nCopyright © 1992\n\
- Michael Saunby"
-
- /*
- * Template etc for ReadArgs() - Pity it can't read tooltypes
- */
- #define TEMPLATE "W=Width/N,H=Height/N,L=LoRes/S"
- #define OPT_WIDTH 0
- #define OPT_HEIGHT 1
- #define OPT_LORES 2
- #define OPT_COUNT 3
-
- struct IntuitionBase *IntuitionBase = NULL;
- struct GfxBase *GfxBase = NULL;
- struct Library *GadToolBase = NULL;
-
- extern struct ExecBase *SysBase;
-
- BOOL restart = FALSE; /* used for resize - see main() */
- UWORD width, height;
- BOOL lores;
- struct Screen *screen;
- struct MsgPort *messageport;
- ULONG allocsignal;
-
- /*
- * Message structure used to get screen size changed, see main()
- */
- struct TestMsg
- {
- struct Message msg;
- USHORT Width;
- USHORT Height;
- BOOL Lores;
- };
-
- /*
- * Easy Requester used for error messages
- */
- struct EasyStruct failedES =
- {sizeof (struct EasyStruct), 0, HAM8_ALBERT_NAME,
- "%s", "OK",};
-
- /*
- * Gadtools menu
- */
- #define ABOUT 1
- #define QUIT 2
- struct NewMenu prj_menu[] =
- {
- {NM_TITLE, "Project", 0, 0, 0, 0,},
- {NM_ITEM, "About...", "?", 0, 0, (void *) ABOUT,},
- {NM_ITEM, "Quit", "Q", 0, 0, (void *) QUIT,},
- {NM_END, NULL, 0, 0, 0, 0,},
- };
-
-
- /*
- * Cleanup() - Close screen and libraries before exit
- */
- VOID Cleanup (VOID);
-
- VOID
- Cleanup ()
- {
- if (restart)
- {
- /*
- * Failed to open screen for client. There is a message port waiting
- * for a reply.
- */
- }
- if (screen)
- {
- CloseScreen (screen);
- FreeSignal (allocsignal);
- }
- if (GadToolBase)
- CloseLibrary (GadToolBase);
- if (IntuitionBase)
- CloseLibrary ((struct Library *) IntuitionBase);
- if (GfxBase)
- CloseLibrary ((struct Library *) GfxBase);
-
- }
-
- /*
- * Quit() - Cleanup and exit on error
- */
- VOID Quit ();
-
- VOID
- Quit (char whytext[], UBYTE failcode)
- {
- EasyRequest (NULL, &failedES, NULL, whytext);
- Cleanup ();
- DeletePort (messageport);
- exit (failcode);
- }
-
- /*
- * CreateScreen() - Main function, build and open a public screen
- */
- VOID
- CreateScreen ( /* USES GLOBALS width, height, lores, restart */ )
- {
- ULONG modeID = HIRESHAMLACE_KEY;
- DisplayInfoHandle displayhandle;
- struct DimensionInfo dimensioninfo;
-
- UWORD maxdepth;
- ULONG soerror = NULL;
- ULONG signal, wsignal, lastsignal;
- ULONG psignal; /* Message port - Another copy of program
- * started */
- struct Task *task;
- BOOL abort = FALSE, closedown = FALSE;
- UWORD oldstatus;
- struct IntuiMessage *msg;
- static struct TestMsg *newdims_msg; /* MUST be static, reply is delayed! */
- struct Window *window;
- struct Menu *menu;
- void *vi;
-
-
- if (lores)
- modeID = HAM_KEY;
-
- if ((GfxBase =
- (struct GfxBase *) OpenLibrary ("graphics.library", 36)) == NULL)
- Quit ("graphics.library is too old <V36", 25);
-
- if ((IntuitionBase =
- (struct IntuitionBase *) OpenLibrary ("intuition.library", 36)) == NULL)
- Quit ("intuition.library is too old <V36", 25);
-
- if ((displayhandle = FindDisplayInfo (modeID)) == NULL)
- Quit ("modeID not found in display database", 25);
-
- if (GetDisplayInfoData (displayhandle, (UBYTE *) & dimensioninfo,
- sizeof (struct DimensionInfo), DTAG_DIMS, NULL) == 0)
- Quit ("mode dimension info not available", 25);
-
- /*
- * Public screen needs a signal and pointer to this task.
- */
- if ((allocsignal = AllocSignal (-1)) == -1)
- Quit ("could not allocate signal", 25);
-
- lastsignal = 1 << allocsignal;
-
- task = (struct Task *) & ((struct Process *) FindTask (NULL))->pr_Task;
-
- /*
- * MaxDepth will always be 8 for Ham8 mode. But it can't hurt.
- */
- maxdepth = dimensioninfo.MaxDepth;
- /*
- * If you always want a standard size just use SA_Overscan, OSCAN_TEXT
- * etc. I have to get the dimensions from dimensioninfo because I always
- * set the width and height.
- */
- if (width == 0)
- width = dimensioninfo.TxtOScan.MaxX - dimensioninfo.TxtOScan.MinX;
- if (height == 0)
- height = dimensioninfo.TxtOScan.MaxY - dimensioninfo.TxtOScan.MinY;
-
- /*
- * Screen is based on workbech to give a familiar look. Could possibly
- * cause problems is the default is a 256 colour WB, must try that
- * sometime and see what happens.
- */
- if ((screen = OpenScreenTags (NULL,
- SA_LikeWorkbench, TRUE, /* see above */
- SA_Overscan, OSCAN_TEXT,
- SA_AutoScroll, TRUE,
- SA_DisplayID, modeID,
- SA_Depth, (UBYTE) maxdepth,
- SA_Width, width,
- SA_Height, height,
- SA_Title, HAM8_ALBERT_NAME,
- SA_PubName, HAM8_ALBERT_NAME,
- SA_PubSig, allocsignal,
- SA_PubTask, task,
- SA_ErrorCode, &soerror,
- SA_SharePens, TRUE,
- TAG_END)) == NULL)
- {
- /*
- * There are many reasons why this might fail, though on an AGA
- * machine only NOCHIPMEM is likely. The other tests are worth
- * keeping for when this code is next used.
- */
- switch (soerror)
- {
- case OSERR_NOCHIPS:
- Quit ("Amiga custom chips not AGA", 25);
- break;
-
- case OSERR_UNKNOWNMODE:
- Quit ("Cannot open screen in this mode", 25);
- break;
-
- case OSERR_NOCHIPMEM:
- Quit ("Not enough CHIP memory", 25);
- break;
-
- case OSERR_NOMEM:
- Quit ("Not enough memory (CHIP or FAST)", 25);
- break;
-
- default:
- Quit ("Unspecified error opening screen", 25);
- break;
- }
- }
- /*
- * StandardPalette() returns number of errors (see display24.c) I ignore
- * the errors here and leave it to the client programs to deal with.
- */
- (VOID) StandardPalette (&(screen->ViewPort), FALSE);
-
- if ((menu = CreateMenus (prj_menu, GTMN_FrontPen, 1, TAG_DONE)) == NULL)
- Quit ("could not build menu", 25);
-
- /*
- * Open a backdrop window to which the above menu is attached.
- */
- if ((window = OpenWindowTags (NULL,
- WA_Top, screen->BarHeight + 1,
- WA_Height, screen->Height -
- (screen->BarHeight + 1),
- WA_CustomScreen, screen,
- WA_NewLookMenus, TRUE,
- WA_IDCMP, MENUPICK,
- WA_Flags, ACTIVATE | BACKDROP | BORDERLESS | NOCAREREFRESH,
- TAG_END)) == NULL)
- Quit ("could not open backdrop window", 25);
-
- /*
- * visual info need to get proper look for menu
- */
- vi = GetVisualInfo (screen, TAG_END);
- if (LayoutMenus (menu, vi, TAG_DONE) == NULL)
- Quit ("could not layout menu", 25);
- FreeVisualInfo (vi);
- SetMenuStrip (window, menu);
-
- /*
- * now go public
- */
- oldstatus = PubScreenStatus (screen, 0);
-
-
- /*
- * come forward if and window opens on this screen
- */
- SetPubScreenModes (POPPUBSCREEN);
-
- if (restart)
- {
- ReplyMsg ((struct Message *) newdims_msg);
- restart = FALSE;
- }
- /*
- * Now wait until told to quit by user (from menu) waiting of course for
- * any visitors to leave.
- */
- psignal = 1 << messageport->mp_SigBit;
- wsignal = 1 << window->UserPort->mp_SigBit;
-
- do
- {
- signal = Wait (wsignal | lastsignal | psignal);
- if (signal & psignal)
- {
- newdims_msg = (struct TestMsg *) GetMsg (messageport);
- width = newdims_msg->Width;
- height = newdims_msg->Height;
- lores = newdims_msg->Lores;
- restart = TRUE;
- /* NB. no reply to message until we have new screen */
- if ((oldstatus = PubScreenStatus (screen,
- PSNF_PRIVATE)) & 1)
- {
- abort = TRUE;
- }
- else
- {
- closedown = TRUE;
- EasyRequest (window, &failedES,
- NULL,
- "Cannot resize yet, there are other programs");
- }
- }
- if (signal & lastsignal)
- {
-
- if (closedown)
- if ((oldstatus = PubScreenStatus (screen, PSNF_PRIVATE))
- & 1)
- abort = TRUE;
- }
- while (msg = (struct IntuiMessage *) GetMsg (window->UserPort))
- {
-
- if (msg->Class == MENUPICK)
- {
- switch ((UWORD) MENU_USERDATA (ItemAddress (menu, msg->Code)))
- {
- case ABOUT:
- EasyRequest (window, &failedES,
- NULL,
- COPYRIGHT_MESSAGE);
- break;
- case QUIT:
- if ((oldstatus = PubScreenStatus (screen,
- PSNF_PRIVATE)) & 1)
- {
- abort = TRUE;
- }
- else
- {
- closedown = TRUE;
- EasyRequest (window, &failedES,
- NULL,
- "Cannot Quit yet,\nthere are other programs");
- }
- break;
- }
- }
- ReplyMsg ((struct Message *) msg);
- }
-
- } while (abort == FALSE);
-
- /*
- * Cleanup part 1. (part 2 is Cleanup())
- */
- ClearMenuStrip (window);
-
- CloseWindow (window);
-
- Cleanup ();
-
- }
-
- /*
- * If another copy of this program is already running we just tell it what
- * size of screen we want then exit.
- */
-
- void
- main ()
- {
- LONG result[OPT_COUNT] =
- {0, 0, 0};
- struct RDArgs *rda;
- BOOL running = FALSE; /* set to true if we find another
- * copy running */
- struct MsgPort *testport, *progport;
- struct TestMsg *msg;
-
- /*
- * Default values - 0 means Text overscan size ie Workbench like defaults
- */
- width = 0;
- height = 0;
- lores = FALSE;
-
- rda = ReadArgs (TEMPLATE, result, NULL);
-
- if (result[OPT_WIDTH])
- width = *(LONG *) result[OPT_WIDTH];
- if (result[OPT_HEIGHT])
- height = *(LONG *) result[OPT_HEIGHT];
- if (result[OPT_LORES])
- lores = TRUE;
- FreeArgs (rda);
-
- /*
- * Check if copy of program running already
- */
- if (testport = CreatePort (NULL, NULL))
- {
- if (msg = AllocMem (sizeof (struct TestMsg), MEMF_PUBLIC | MEMF_CLEAR))
- {
- msg->msg.mn_ReplyPort = testport;
- msg->msg.mn_Length = sizeof (struct TestMsg);
- msg->Width = width;
- msg->Height = height;
- msg->Lores = lores;
- Forbid ();
- if (progport = FindPort (HAM8_ALBERT_NAME))
- {
- PutMsg (progport, (struct Message *) msg);
- Permit ();
- WaitPort (testport);
- msg = (struct TestMsg *) GetMsg (testport);
- running = TRUE;
- }
- Permit ();
- FreeMem (msg, (ULONG) sizeof (struct TestMsg));
- }
- DeletePort (testport);
- }
- if (running)
- return;
-
- messageport = CreatePort (HAM8_ALBERT_NAME, NULL);
-
- /*
- * Go around this loop each time the screen is resized. al-backdrop.c
- * uses this feature.
- */
- do
- {
- CreateScreen (lores, width, height);
- } while (restart);
- DeletePort (messageport);
- }
-